package com.zhangfb95.crosschain.console.service.impl;

import com.zhangfb95.crosschain.console.service.ConsoleService;
import com.zhangfb95.crosschain.console.service.CommandService;
import com.zhangfb95.crosschain.console.util.TokenUtil;
import com.zhangfb95.crosschain.sdk.CrossChainClient;
import com.zhangfb95.crosschain.sdk.infra.model.service.dto.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.jline.reader.LineReader;
import org.jline.reader.LineReaderBuilder;
import org.jline.terminal.Terminal;
import org.jline.terminal.TerminalBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author zhangfubing
 * @since 2023/12/21
 */
@Slf4j
@Service
public class ConsoleServiceImpl implements ConsoleService {

    @Autowired
    private CommandService commandService;
    @Autowired
    private CrossChainClient crossChainClient;

    @Override
    public void start() {
        try {
            Terminal terminal = TerminalBuilder.builder()
                    .nativeSignals(true)
                    .signalHandler(Terminal.SignalHandler.SIG_IGN)
                    .build();
            LineReader reader = LineReaderBuilder.builder()
                    .terminal(terminal)
                    .option(LineReader.Option.HISTORY_IGNORE_SPACE, false)
                    .option(LineReader.Option.HISTORY_REDUCE_BLANKS, false)
                    .build();

            while (true) {
                try {
                    String prompt;
                    UserInfo userInfo = crossChainClient.getLoginedUserInfo();
                    if (userInfo != null) {
                        prompt = "[" + userInfo.getUsername() + "@Cross]> ";
                    } else {
                        prompt = "[Cross]> ";
                    }
                    String line = reader.readLine(prompt);
                    if (handle(line)) {
                        break;
                    }
                } catch (Exception e) {
                    log.error(e.toString(), e);
                }
            }
        } catch (Exception e) {
            log.error(e.toString(), e);
        }
    }

    private boolean handle(String line) {
        String[] commandAndArgs = TokenUtil.tokenizeCommand(line);
        if (commandAndArgs.length < 1) {
            return false;
        }

        String command = commandAndArgs[0];
        if (command.trim().isEmpty()) {
            return false;
        }
        String[] args;
        if (commandAndArgs.length > 1) {
            args = new String[commandAndArgs.length - 1];
            System.arraycopy(commandAndArgs, 1, args, 0, commandAndArgs.length - 1);
        } else {
            args = new String[0];
        }

        try {
            return commandService.get(command).handle(args);
        } catch (RuntimeException e) {
            System.out.println("Result Exception: " + e.getMessage());
        }
        return false;
    }
}
